package org.mybatis.generator.plugins.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.tools.ant.util.DateUtils;
import org.mybatis.generator.api.GeneratedJavaFile;
import org.mybatis.generator.api.GeneratedJavaScriptFile;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.OutputUtilities;
import org.mybatis.generator.api.dom.java.CompilationUnit;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.Interface;
import org.mybatis.generator.api.dom.java.JavaElement;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.Parameter;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.internal.util.StringUtility;

/**
 * 生成service类
 * 
 */
public class AdminServicePlugin extends PluginAdapter {

	private FullyQualifiedJavaType slf4jLogger;
	private FullyQualifiedJavaType slf4jLoggerFactory;
	private FullyQualifiedJavaType serviceType;
	private FullyQualifiedJavaType daoType;
	private FullyQualifiedJavaType interfaceType;
	private FullyQualifiedJavaType pojoType;
	private FullyQualifiedJavaType pojoCriteriaType;
	private FullyQualifiedJavaType qoType;
	private FullyQualifiedJavaType boType;
	private FullyQualifiedJavaType orderType;
	private FullyQualifiedJavaType pageBoundsType;
	private FullyQualifiedJavaType listType;
	private FullyQualifiedJavaType autowired;
	private FullyQualifiedJavaType transactional;
	private FullyQualifiedJavaType service;
	private FullyQualifiedJavaType returnType;
	private FullyQualifiedJavaType serviceExceptionType;
	private FullyQualifiedJavaType serializable;
	private FullyQualifiedJavaType pageList;
	private FullyQualifiedJavaType arrayList;
	private FullyQualifiedJavaType dateType;
	private FullyQualifiedJavaType idHelper;
	private String servicePack;
	private String project;
	private String pojoUrl;
	private String qoUrl;
	private String boUrl;
	private String pageBoundsUrl = "com.github.miemiedev.mybatis.paginator.domain.PageBounds";
	private String orderUrl = "com.github.miemiedev.mybatis.paginator.domain.Order";
	private String model = "admin";

	private List<Method> methods;
	/**
	 * 是否添加注解
	 */
	private boolean enableAnnotation = true;
	private boolean enableCount = false;
	private boolean enableSelectByPrimaryKey = false;
	private boolean enableSelectByExample = false;
	private boolean enableSelectPageByExample = false;
	private boolean enableSelectAllByExample = false;
	private boolean enableSelectSimpleByExample = false;
	private boolean enableIsUniqueByExample = false;
	private boolean enableInsert = false;
	private boolean enableInsertSelective = false;
	private boolean enableDeleteByPrimaryKey = false;
	private boolean enableDeleteByExample = false;
	private boolean enableBatchDeleteByExample = false;
	private boolean enableUpdateByExample = false;
	private boolean enableUpdateByExampleSelective = false;
	private boolean enableUpdateByPrimaryKey = false;
	private boolean enableUpdateByPrimaryKeySelective = false;
	private boolean enableBatchUpdateByExample = false;

	public AdminServicePlugin() {
		super();
		// 默认是slf4j
		serializable = new FullyQualifiedJavaType("java.io.Serializable");
		slf4jLogger = new FullyQualifiedJavaType("org.slf4j.Logger");
		slf4jLoggerFactory = new FullyQualifiedJavaType(
				"org.slf4j.LoggerFactory");
		pageList = new FullyQualifiedJavaType(
				"com.github.miemiedev.mybatis.paginator.domain.PageList");
		arrayList = new FullyQualifiedJavaType("java.util.ArrayList");
		dateType = new FullyQualifiedJavaType("java.util.Date");
		idHelper = new FullyQualifiedJavaType(
				"com.mingyuan.life.utils.IdUtils");
		methods = new ArrayList<Method>();
	}

	@Override
	public boolean validate(List<String> warnings) {
		if (StringUtility.stringHasValue(properties
				.getProperty("enableAnnotation")))
			enableAnnotation = StringUtility.isTrue(properties
					.getProperty("enableAnnotation"));

		String enableCount = properties.getProperty("enableCount");
		String enableSelectByPrimaryKey = properties
				.getProperty("enableSelectByPrimaryKey");
		String enableSelectByExample = properties
				.getProperty("enableSelectByExample");
		String enableSelectPageByExample = properties
				.getProperty("enableSelectPageByExample");
		String enableSelectSimpleByExample = properties
				.getProperty("enableSelectSimpleByExample");
		String enableSelectAllByExample = properties
				.getProperty("enableSelectAllByExample");
		String enableIsUniqueByExample = properties
				.getProperty("enableIsUniqueByExample");

		String enableInsert = properties.getProperty("enableInsert");

		String enableUpdateByExampleSelective = properties
				.getProperty("enableUpdateByExampleSelective");

		String enableInsertSelective = properties
				.getProperty("enableInsertSelective");

		String enableUpdateByPrimaryKey = properties
				.getProperty("enableUpdateByPrimaryKey");

		String enableDeleteByPrimaryKey = properties
				.getProperty("enableDeleteByPrimaryKey");

		String enableDeleteByExample = properties
				.getProperty("enableDeleteByExample");

		String enableBatchDeleteByExample = properties
				.getProperty("enableBatchDeleteByExample");

		String enableUpdateByPrimaryKeySelective = properties
				.getProperty("enableUpdateByPrimaryKeySelective");

		String enableUpdateByExample = properties
				.getProperty("enableUpdateByExample");
		String enableBatchUpdateByExample = properties
				.getProperty("enableBatchUpdateByExample");

		if (StringUtility.stringHasValue(enableCount))
			this.enableCount = StringUtility.isTrue(enableCount);
		if (StringUtility.stringHasValue(enableSelectByPrimaryKey))
			this.enableSelectByPrimaryKey = StringUtility
					.isTrue(enableSelectByPrimaryKey);
		if (StringUtility.stringHasValue(enableSelectByExample))
			this.enableSelectByExample = StringUtility
					.isTrue(enableSelectByExample);
		if (StringUtility.stringHasValue(enableSelectAllByExample))
			this.enableSelectAllByExample = StringUtility
					.isTrue(enableSelectAllByExample);
		if (StringUtility.stringHasValue(enableSelectPageByExample))
			this.enableSelectPageByExample = StringUtility
					.isTrue(enableSelectPageByExample);
		if (StringUtility.stringHasValue(enableSelectSimpleByExample))
			this.enableSelectSimpleByExample = StringUtility
					.isTrue(enableSelectSimpleByExample);
		if (StringUtility.stringHasValue(enableInsert))
			this.enableInsert = StringUtility.isTrue(enableInsert);
		if (StringUtility.stringHasValue(enableUpdateByExampleSelective))
			this.enableUpdateByExampleSelective = StringUtility
					.isTrue(enableUpdateByExampleSelective);
		if (StringUtility.stringHasValue(enableIsUniqueByExample))
			this.enableIsUniqueByExample = StringUtility
					.isTrue(enableIsUniqueByExample);
		if (StringUtility.stringHasValue(enableInsertSelective))
			this.enableInsertSelective = StringUtility
					.isTrue(enableInsertSelective);
		if (StringUtility.stringHasValue(enableUpdateByPrimaryKey))
			this.enableUpdateByPrimaryKey = StringUtility
					.isTrue(enableUpdateByPrimaryKey);
		if (StringUtility.stringHasValue(enableDeleteByPrimaryKey))
			this.enableDeleteByPrimaryKey = StringUtility
					.isTrue(enableDeleteByPrimaryKey);
		if (StringUtility.stringHasValue(enableDeleteByExample))
			this.enableDeleteByExample = StringUtility
					.isTrue(enableDeleteByExample);
		if (StringUtility.stringHasValue(enableBatchDeleteByExample))
			this.enableBatchDeleteByExample = StringUtility
					.isTrue(enableBatchDeleteByExample);
		if (StringUtility.stringHasValue(enableUpdateByPrimaryKeySelective))
			this.enableUpdateByPrimaryKeySelective = StringUtility
					.isTrue(enableUpdateByPrimaryKeySelective);
		if (StringUtility.stringHasValue(enableUpdateByExample))
			this.enableUpdateByExample = StringUtility
					.isTrue(enableUpdateByExample);
		if (StringUtility.stringHasValue(enableBatchUpdateByExample))
			this.enableBatchUpdateByExample = StringUtility
					.isTrue(enableBatchUpdateByExample);
		servicePack = properties.getProperty("targetPackage");
		project = properties.getProperty("targetProject");

		pojoUrl = context.getJavaModelGeneratorConfiguration()
				.getTargetPackage();
		qoUrl = context.getJavaModelGeneratorConfiguration().getTargetPackage();
		boUrl = context.getJavaModelGeneratorConfiguration().getTargetPackage();
		if (enableAnnotation) {
			autowired = new FullyQualifiedJavaType(
					"org.springframework.beans.factory.annotation.Autowired");
			transactional = new FullyQualifiedJavaType(
					"org.springframework.transaction.annotation.Transactional");
			service = new FullyQualifiedJavaType(
					"org.springframework.stereotype.Service");
		}
		return true;
	}

	@Override
	public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(
			IntrospectedTable introspectedTable) {
		List<GeneratedJavaFile> files = new ArrayList<GeneratedJavaFile>();
		String table = introspectedTable.getBaseRecordType();
		String tableName = table.replaceAll(this.pojoUrl + ".", "");
		interfaceType = new FullyQualifiedJavaType(servicePack + "."
				+ util.StringUtils.replaceLast(tableName,"Po","") + "Service");
		// mybatis
		daoType = new FullyQualifiedJavaType(
				introspectedTable.getMyBatis3JavaMapperType());
		serviceType = new FullyQualifiedJavaType(servicePack + "."
				+ util.StringUtils.replaceLast(tableName,"Po","") + "Service");
		pojoType = new FullyQualifiedJavaType(pojoUrl + "." + tableName);
		qoUrl = qoUrl.replace(".po.", ".qo.");
		boUrl = boUrl.replace(".po.", ".bo.");
		int voIndex = qoUrl.lastIndexOf(".qo");
		int baseIndex = qoUrl.lastIndexOf(".model");
		String baseRespUrl = qoUrl.substring(0, voIndex + 1);
		String exceptionUrl = qoUrl.substring(0, baseIndex + 1);
		boType = new FullyQualifiedJavaType(boUrl + "."
				+ util.StringUtils.replaceLast(tableName,"Po","Bo"));
		qoType = new FullyQualifiedJavaType(qoUrl + "."
				+ util.StringUtils.replaceLast(tableName,"Po","Qo"));
		//serviceExceptionType = new FullyQualifiedJavaType(exceptionUrl + model+ ".exception.ServiceException");
		serviceExceptionType = new FullyQualifiedJavaType(exceptionUrl + "exception.ServiceException");
		pageBoundsType = new FullyQualifiedJavaType(pageBoundsUrl);
		orderType = new FullyQualifiedJavaType(orderUrl);

		listType = new FullyQualifiedJavaType("java.util.List");
		Interface interface1 = new Interface(interfaceType);
		TopLevelClass topLevelClass = new TopLevelClass(serviceType);
		// 导入必要的类
		addImport(interface1, topLevelClass);
		// 添加实现类
		addService(topLevelClass, introspectedTable, tableName, files);
		// 添加日志
		addLogger(topLevelClass);

		return files;
	}

	/**
	 * 添加实现类
	 * 
	 * @param introspectedTable
	 * @param tableName
	 * @param files
	 */
	protected void addService(TopLevelClass topLevelClass,
			IntrospectedTable introspectedTable, String tableName,
			List<GeneratedJavaFile> files) {
		topLevelClass.setVisibility(JavaVisibility.PUBLIC);
		// 设置实现的接口
		// topLevelClass.addSuperInterface(interfaceType);
		if (enableAnnotation) {
			topLevelClass.addAnnotation("@Service");
			topLevelClass.addAnnotation("@Transactional");
			topLevelClass.addImportedType(service);
		}

		// 添加引用dao
		addField(topLevelClass, tableName);
		// 添加方法
		Method method = null;

		/**
		 * type 的意义 pojo 1 ;key 2 ;example 3 ;pojo+example 4
		 */

		if (enableInsert) {
			method = getOtherInsertBaseResp("insert", introspectedTable,
					tableName);
			addMethodComment(method, "保存记录,不管记录里面的属性是否为空");
			// addMethodAnnotation(method);
			topLevelClass.addMethod(method);
		}
		enableInsertSelective = false;
		if (enableInsertSelective) {
			method = getOtherInsertBaseResp("insert", introspectedTable,
					tableName);
			addMethodComment(method, "保存属性不为空的记录");
			// addMethodAnnotation(method);
			topLevelClass.addMethod(method);
		}

		if (enableDeleteByPrimaryKey) {
			method = getOtherBaseResp("deleteById", "deleteById",
					introspectedTable, tableName, 2);
			addMethodComment(method, "根据主键删除记录");
			// addMethodAnnotation(method);
			topLevelClass.addMethod(method);
		}
		enableDeleteByExample = false;
		if (enableDeleteByExample) {
			method = getOtherBaseResp("delete", "deleteBy" + tableName,
					introspectedTable, tableName, 5);
			addMethodComment(method, "根据条件删除记录");
			// addMethodAnnotation(method);
			topLevelClass.addMethod(method);
		}

		// 批量删除
		if (enableBatchDeleteByExample) {
			method = null;
			method = batchDeleteByExample(introspectedTable, tableName);
			addMethodComment(method, "根据ids批量删除记录");
			// addMethodAnnotation(method);
			topLevelClass.addMethod(method);
		}

		enableUpdateByPrimaryKey = false;
		if (enableUpdateByPrimaryKey) {
			method = getOtherBaseResp("updateById", "updateByPrimaryKey",
					introspectedTable, tableName, 1);
			addMethodComment(method, "根据主键更新记录");
			// addMethodAnnotation(method);
			topLevelClass.addMethod(method);
		}
		if (enableUpdateByPrimaryKeySelective) {
			method = getOtherBaseResp("updateById", "updateById",
					introspectedTable, tableName, 1);
			addMethodComment(method, "根据条件更新属性不为空的记录");
			// addMethodAnnotation(method);
			topLevelClass.addMethod(method);

		}
		enableUpdateByExampleSelective = false;
		if (enableUpdateByExampleSelective) {
			method = getOtherBaseResp("update", "updateBy" + tableName
					+ "Selective", introspectedTable, tableName, 6);
			addMethodComment(method, "根据条件更新属性不为空的记录");
			// addMethodAnnotation(method);
			topLevelClass.addMethod(method);
		}
		enableUpdateByExample = false;
		if (enableUpdateByExample) {
			method = getOtherBaseResp("update", "updateBy" + tableName,
					introspectedTable, tableName, 6);
			addMethodComment(method, "根据条件更新记录");
			// addMethodAnnotation(method);
			topLevelClass.addMethod(method);
		}

		// 批量修改
		if (enableBatchUpdateByExample) {
			method = null;
			method = batchModifyExample(introspectedTable, tableName);
			addMethodComment(method, "根据ids批量修改记录");
			// addMethodAnnotation(method);
			topLevelClass.addMethod(method);
		}

		// 统计
		if (enableCount) {
			method = countByExample(introspectedTable, tableName);
			addMethodComment(method, "根据主键查询记录");
			// addMethodAnnotation(method);
			topLevelClass.addMethod(method);
		}
		// 根据主键查询
		if (enableSelectByPrimaryKey) {
			method = null;
			method = selectByPrimaryKey(introspectedTable, tableName);
			addMethodComment(method, "根据主键查询记录");
			// addMethodAnnotation(method);
			topLevelClass.addMethod(method);
		}
		// 根据条件查询-组件分页
		if (enableSelectByExample) {
			method = null;
			method = selectByExample(introspectedTable, tableName);
			addMethodComment(method, "根据条件分页查询记录集-组件分页");
			// addMethodAnnotation(method);
			topLevelClass.addMethod(method);
		}
		// 分页查询-采用SQL分页
		enableSelectPageByExample = false;
		if (enableSelectPageByExample) {
			method = null;
			method = selectPageByExample(introspectedTable, tableName);
			addMethodComment(method, "根据条件分页查询所有记录集-sql分页");
			// addMethodAnnotation(method);
			topLevelClass.addMethod(method);
		}
		// 根据条件查询所有记录
		if (enableSelectAllByExample) {
			method = null;
			method = selectAllByExample(introspectedTable, tableName);
			addMethodComment(method, "根据条件查询所有简单记录集");
			// addMethodAnnotation(method);
			topLevelClass.addMethod(method);
		}
		// 查询所有简单记录
		enableSelectSimpleByExample = false;
		if (enableSelectSimpleByExample) {
			method = null;
			method = selectSimpleByExample(introspectedTable, tableName);
			addMethodComment(method, "根据条件查询所有简单记录集");
			// addMethodAnnotation(method);
			topLevelClass.addMethod(method);
		}
		// 校验是否唯一
		if (enableIsUniqueByExample) {
			method = null;
			method = isUniqueByExample(introspectedTable, tableName);
			addMethodComment(method, "根据条件查询判断记录是否唯一");
			// addMethodAnnotation(method);
			topLevelClass.addMethod(method);
		}
		method = null;
		method = queryByNameExample(introspectedTable, tableName);
		addMethodComment(method, "根据ID查询记录名称");
		topLevelClass.addMethod(method);
		// 添加调试方法
		// method = null;
		// method = addDebugMethod();
		// topLevelClass.addMethod(method);

		topLevelClass.addFileCommentLine(util.StringUtils.replaceLast(introspectedTable.getTableConfiguration().getTableName(),"Po","")
				+ "Service");
		topLevelClass
				.addFileCommentLine(introspectedTable.getRemarks() + "服务类");
		addJavaFileComment(topLevelClass);

		// 生成文件
		GeneratedJavaFile file = new GeneratedJavaFile(topLevelClass, project);
		files.add(file);
	}

	/**
	 * 添加字段
	 * 
	 * @param topLevelClass
	 */
	protected void addField(TopLevelClass topLevelClass, String tableName) {
		// 添加 dao
		Field field = new Field();
		field.setName(toLowerCase(daoType.getShortName())); // 设置变量名
		topLevelClass.addImportedType(daoType);
		field.setType(daoType); // 类型
		field.setVisibility(JavaVisibility.PRIVATE);
		if (enableAnnotation) {
			field.addAnnotation("@Autowired");
		}
		topLevelClass.addField(field);
	}

	/**
	 * 添加方法
	 * 
	 */
	protected Method selectByPrimaryKey(IntrospectedTable introspectedTable,
			String tableName) {
		Method method = new Method();
		method.setName("queryById");
		method.setReturnType(boType);
		method.setReturnRemark("返回业务对象");
		if (introspectedTable.getRules().generatePrimaryKeyClass()) {
			FullyQualifiedJavaType type = new FullyQualifiedJavaType(
					introspectedTable.getPrimaryKeyType());
			method.addParameter(new Parameter(type, "key"));
		} else {
			for (IntrospectedColumn introspectedColumn : introspectedTable
					.getPrimaryKeyColumns()) {
				FullyQualifiedJavaType type = introspectedColumn
						.getFullyQualifiedJavaType();
				Parameter parameter = new Parameter(type,
						introspectedColumn.getJavaProperty());
				parameter.setRemark("主键");
				method.addParameter(parameter);
			}
		}
		method.setVisibility(JavaVisibility.PUBLIC);
		StringBuilder sb = new StringBuilder();
		method.addBodyLine("try {");
		sb.append(tableName + " record= this.");
		sb.append(getDaoShort());
		sb.append("queryById");
		sb.append("(");
		for (IntrospectedColumn introspectedColumn : introspectedTable
				.getPrimaryKeyColumns()) {
			sb.append(introspectedColumn.getJavaProperty());
			sb.append(",");
		}
		sb.setLength(sb.length() - 1);
		sb.append(");");
		method.addBodyLine(sb.toString());
		method.addBodyLine("if(record!=null){");
		method.addBodyLine(util.StringUtils.replaceLast(tableName,"Po","") + "Bo bo= new "
				+ util.StringUtils.replaceLast(tableName,"Po","") + "Bo(record);");
		// method.addBodyLine("BeanUtils.copyProperties(record, resp);");
		method.addBodyLine("return bo;");
		method.addBodyLine("}");
		method.addBodyLine("} catch (ServiceException e) {");
		method.addBodyLine("logger.error(\"service Exception: \", e);");
		method.addBodyLine("}");
		method.addBodyLine("return null;");
		return method;
	}

	/**
	 * 添加方法
	 * 
	 */
	protected Method addDebugMethod() {
		Method method = new Method();
		method.setName("debug");
		method.addParameter(new Parameter(FullyQualifiedJavaType
				.getStringInstance(), "serviceName"));
		method.addParameter(new Parameter(serializable, "req"));
		method.setVisibility(JavaVisibility.PUBLIC);
		method.addBodyLine("if (logger.isDebugEnabled()) {");
		method.addBodyLine(" logger.debug(\" {}: {}\",new Object[]{ serviceName, req});");
		method.addBodyLine("}");
		addMethodComment(method, "Debug模式下调试客户端信息");

		return method;
	}

	/**
	 * 统计
	 * 
	 * @param introspectedTable
	 * @param tableName
	 * @return
	 */
	protected Method countByExample(IntrospectedTable introspectedTable,
			String tableName) {
		Method method = new Method();
		// //method.setName("countBy" + tableName);
		method.setName("count");
		method.setReturnType(FullyQualifiedJavaType.getIntInstance());
		method.setReturnRemark("返回统计结果");
		Parameter parameter = new Parameter(qoType, "qo");
		parameter.setRemark("条件查询对象");
		method.addParameter(parameter);
		method.setVisibility(JavaVisibility.PUBLIC);
		// method.addBodyLine(" debug(\"" + method.getName() + "\", qo);");
		method.addBodyLine("try {");
		StringBuilder sb = new StringBuilder();
		sb.append("int count = this.");
		sb.append(getDaoShort());
		sb.append("count");
		sb.append("(");
		sb.append("qo");
		sb.append(");");
		method.addBodyLine(sb.toString());
		method.addBodyLine("logger.debug(\"count: {}\", count);");
		method.addBodyLine("return count;");
		method.addBodyLine(" } catch (ServiceException e) {");
		method.addBodyLine("logger.error(\"service Exception: \", e);");
		method.addBodyLine("return 0;");
		method.addBodyLine(" }");

		return method;
	}

	/**
	 * 分页查询
	 * 
	 */
	protected Method selectByExample(IntrospectedTable introspectedTable,
			String tableName) {
		Method method = new Method();
		// method.setName("selectBy" + tableName);
		method.setName("query");
		method.setReturnType(new FullyQualifiedJavaType("List<"
				+ util.StringUtils.replaceLast(tableName,"Po","") + "Bo>"));
		method.setReturnRemark("返回业务对象列表");
		Parameter parameter = new Parameter(qoType, "qo");
		parameter.setRemark("条件查询对象");
		method.addParameter(parameter);
		method.setVisibility(JavaVisibility.PUBLIC);
		// method.addBodyLine(" debug(\"" + method.getName() + "\", qo);");
		method.addBodyLine("try {");
		StringBuilder sb = new StringBuilder();

		sb.append("PageBounds pbs = new PageBounds(");
		sb.append("qo.getPageNumber(), qo.getPageSize(),Order.formString(\"createTime.desc\")");
		sb.append(");");
		method.addBodyLine(sb.toString());

		sb = new StringBuilder();
		sb.append("PageList<" + tableName + "> records = (PageList<"
				+ tableName + ">) this.");
		sb.append(getDaoShort());
		if (introspectedTable.hasBLOBColumns()) {
			sb.append("query");
		} else {
			sb.append("query");
		}
		sb.append("(");
		sb.append("qo,pbs");
		sb.append(");");
		method.addBodyLine(sb.toString());

		method.addBodyLine("List<" + util.StringUtils.replaceLast(tableName,"Po","")
				+ "Bo> bos=new ArrayList<" + util.StringUtils.replaceLast(tableName,"Po","")
				+ "Bo>();");
		method.addBodyLine(util.StringUtils.replaceLast(tableName,"Po","") + "Bo bo=null;");
		method.addBodyLine("for(" + tableName + " record:records){");
		method.addBodyLine("bo=new " + util.StringUtils.replaceLast(tableName,"Po","")
				+ "Bo(record);");
		// method.addBodyLine(" BeanUtils.copyProperties(record, bo);");
		method.addBodyLine(" bos.add(bo);");
		method.addBodyLine(" }");
		method.addBodyLine("PageList<" + util.StringUtils.replaceLast(tableName,"Po","")
				+ "Bo> resp=new PageList<" + util.StringUtils.replaceLast(tableName,"Po","")
				+ "Bo>(bos, records.getPaginator());");
		method.addBodyLine("return resp;");

		method.addBodyLine(" } catch (ServiceException e) {");
		method.addBodyLine("logger.error(\"service Exception: \", e);");
		method.addBodyLine("return null;");
		method.addBodyLine(" }");

		return method;
	}

	/**
	 * 添加方法
	 * 
	 */
	protected Method selectPageByExample(IntrospectedTable introspectedTable,
			String tableName) {
		Method method = new Method();
		// method.setName("selectPageBy" + tableName);
		method.setName("queryByPage");
		method.setReturnType(new FullyQualifiedJavaType("List<"
				+ util.StringUtils.replaceLast(tableName,"Po","") + "Bo>"));
		method.setReturnRemark("返回业务对象列表");
		Parameter parameter = new Parameter(qoType, "qo");
		parameter.setRemark("条件查询对象");
		method.addParameter(parameter);
		method.setVisibility(JavaVisibility.PUBLIC);

		// method.addBodyLine(" debug(\"" + method.getName() + "\", qo);");
		method.addBodyLine("try {");

		StringBuilder sb = new StringBuilder();

		sb.append("Integer totalSize = this.");
		sb.append(getDaoShort());
		sb.append("countBy" + tableName);
		sb.append("(qo);");
		method.addBodyLine(sb.toString());
		sb = new StringBuilder();
		method.addBodyLine("qo.setTotalSize(totalSize);");

		sb.append("List<" + tableName + "> records = (List<" + tableName
				+ ">) this.");
		sb.append(getDaoShort());
		if (introspectedTable.hasBLOBColumns()) {
			sb.append("selectBy" + tableName + "WithoutBLOBs");
		} else {
			sb.append("selectBy" + tableName);
		}
		sb.append("(");
		sb.append("qo");
		sb.append(");");
		method.addBodyLine(sb.toString());

		method.addBodyLine("List<" + util.StringUtils.replaceLast(tableName,"Po","")
				+ "Bo> bos=new ArrayList<" + tableName + "Bo>();");
		method.addBodyLine(util.StringUtils.replaceLast(tableName,"Po","") + "Bo bo=null;");
		method.addBodyLine("for(" + tableName + " record:records){");
		method.addBodyLine("bo=new " + util.StringUtils.replaceLast(tableName,"Po","")
				+ "Bo(record);");
		// method.addBodyLine(" BeanUtils.copyProperties(record, bo);");
		method.addBodyLine(" bos.add(bo);");
		method.addBodyLine(" }");
		method.addBodyLine("return bos;");

		method.addBodyLine(" } catch (ServiceException e) {");
		method.addBodyLine("logger.error(\"service Exception: \", e);");
		method.addBodyLine("return null;");
		method.addBodyLine(" }");

		return method;
	}

	/**
	 * 查询所有记录
	 * 
	 */
	protected Method selectAllByExample(IntrospectedTable introspectedTable,
			String tableName) {
		Method method = new Method();
		method.setName("queryByAll");
		method.setReturnType(new FullyQualifiedJavaType("List<"
				+ util.StringUtils.replaceLast(tableName,"Po","Bo") + ">"));
		method.setReturnRemark("返回业务对象列表");
		Parameter parameter = new Parameter(qoType, "qo");
		parameter.setRemark("条件查询对象");
		method.addParameter(parameter);
		method.setVisibility(JavaVisibility.PUBLIC);

		// method.addBodyLine(" debug(\"" + method.getName() + "\", qo);");
		method.addBodyLine("try {");

		StringBuilder sb = new StringBuilder();
		sb.append("List<" + tableName + "> records =  this.");
		sb.append(getDaoShort());
		if (introspectedTable.hasBLOBColumns()) {
			sb.append("query");
		} else {
			sb.append("query");
		}
		sb.append("(");
		sb.append("qo");
		sb.append(");");
		method.addBodyLine(sb.toString());

		method.addBodyLine("List<" + util.StringUtils.replaceLast(tableName,"Po","")
				+ "Bo> bos=new ArrayList<" + util.StringUtils.replaceLast(tableName,"Po","")
				+ "Bo>();");
		method.addBodyLine(util.StringUtils.replaceLast(tableName,"Po","") + "Bo bo=null;");
		method.addBodyLine("for(" + tableName + " record:records){");
		method.addBodyLine("bo=new " + util.StringUtils.replaceLast(tableName,"Po","")
				+ "Bo(record);");
		// method.addBodyLine(" BeanUtils.copyProperties(record, bo);");
		method.addBodyLine(" bos.add(bo);");
		method.addBodyLine(" }");
		method.addBodyLine("return bos;");

		method.addBodyLine(" } catch (ServiceException e) {");
		method.addBodyLine("logger.error(\"service Exception: \", e);");
		method.addBodyLine("return null;");
		method.addBodyLine(" }");

		return method;
	}

	/**
	 * 根据条件判断是否唯一
	 * 
	 */
	protected Method isUniqueByExample(IntrospectedTable introspectedTable,
			String tableName) {
		Method method = new Method();
		// method.setName("isUniqueBy" + tableName);
		method.setName("isUnique");
		method.setReturnType(FullyQualifiedJavaType
				.getBooleanPrimitiveInstance());
		method.setReturnRemark("返回True Or  Flase");

		Parameter parameter = new Parameter(
				new FullyQualifiedJavaType("String"), "name");
		parameter.setRemark("名称");
		method.addParameter(parameter);

		parameter = new Parameter(new FullyQualifiedJavaType("Long"),
				"exclusionId");
		parameter.setRemark("过滤ID");
		method.addParameter(parameter);

		method.setVisibility(JavaVisibility.PUBLIC);

		// method.addBodyLine(" debug(\"" + method.getName() + "\", qo);");
		method.addBodyLine("try {");

		method.addBodyLine(util.StringUtils.replaceLast(tableName,"Po","") + "Qo qo=new "
				+ util.StringUtils.replaceLast(tableName,"Po","") + "Qo();");
		method.addBodyLine("qo.setId(exclusionId);");
		StringBuilder sb = new StringBuilder();
		sb.append("int count = this.");
		sb.append(getDaoShort());
		sb.append("isUnique");
		sb.append("(");
		sb.append("qo");
		sb.append(");");
		method.addBodyLine(sb.toString());

		method.addBodyLine(" if(count>0){");
		method.addBodyLine(" return false;");
		method.addBodyLine(" }");
		method.addBodyLine("return true;");

		method.addBodyLine(" } catch (ServiceException e) {");
		method.addBodyLine("logger.error(\"service Exception: \", e);");
		method.addBodyLine("return false;");
		method.addBodyLine(" }");
		return method;
	}

	/**
	 * 根据条件判断是否唯一
	 * 
	 */
	protected Method queryByNameExample(IntrospectedTable introspectedTable,
			String tableName) {
		Method method = new Method();
		method.setName("queryByName");
		method.setReturnType(FullyQualifiedJavaType.getStringInstance());
		method.setReturnRemark("返回业务对象名称");
		if (introspectedTable.getRules().generatePrimaryKeyClass()) {
			FullyQualifiedJavaType type = new FullyQualifiedJavaType(
					introspectedTable.getPrimaryKeyType());
			method.addParameter(new Parameter(type, "key"));
		} else {
			for (IntrospectedColumn introspectedColumn : introspectedTable
					.getPrimaryKeyColumns()) {
				FullyQualifiedJavaType type = introspectedColumn
						.getFullyQualifiedJavaType();
				Parameter parameter = new Parameter(type,
						introspectedColumn.getJavaProperty());
				parameter.setRemark("主键");
				method.addParameter(parameter);
			}
		}
		method.setVisibility(JavaVisibility.PUBLIC);
		StringBuilder sb = new StringBuilder();
		method.addBodyLine("try {");
		sb.append(tableName + " record= this.");
		sb.append(getDaoShort());
		sb.append("queryById");
		sb.append("(");
		for (IntrospectedColumn introspectedColumn : introspectedTable
				.getPrimaryKeyColumns()) {
			sb.append(introspectedColumn.getJavaProperty());
			sb.append(",");
		}
		sb.setLength(sb.length() - 1);
		sb.append(");");
		method.addBodyLine(sb.toString());
		method.addBodyLine("if(record!=null){");
		// method.addBodyLine("BeanUtils.copyProperties(record, resp);");
		method.addBodyLine("return \"\";");
		method.addBodyLine("}");
		method.addBodyLine("} catch (ServiceException e) {");
		method.addBodyLine("logger.error(\"service Exception: \", e);");
		method.addBodyLine("}");
		method.addBodyLine("return \"\";");
		return method;
	}

	/**
	 * 查询所有记录，只返回部分字段
	 * 
	 */
	protected Method selectSimpleByExample(IntrospectedTable introspectedTable,
			String tableName) {
		Method method = new Method();
		method.setName("selectSimpleBy" + tableName);
		method.setReturnType(new FullyQualifiedJavaType("List<" + tableName
				+ "Bo>"));
		method.setReturnRemark("返回业务对象列表");
		Parameter parameter = new Parameter(qoType, "qo");
		parameter.setRemark("条件查询对象");
		method.addParameter(parameter);
		method.setVisibility(JavaVisibility.PUBLIC);

		// method.addBodyLine(" debug(\"" + method.getName() + "\", qo);");
		method.addBodyLine("try {");

		StringBuilder sb = new StringBuilder();
		sb.append("List<" + tableName + "> records = (List<" + tableName
				+ ">) this.");
		sb.append(getDaoShort());
		if (introspectedTable.hasBLOBColumns()) {
			sb.append("selectBy" + tableName + "WithoutBLOBs");
		} else {
			sb.append("selectBy" + tableName);
		}
		sb.append("(");
		sb.append("qo");
		sb.append(");");
		method.addBodyLine(sb.toString());

		method.addBodyLine("List<" + tableName + "Bo> bos=new ArrayList<"
				+ tableName + "Bo>();");
		method.addBodyLine(tableName + "Bo bo=null;");
		method.addBodyLine("for(" + tableName + " record:records){");
		method.addBodyLine("bo=new " + tableName + "Bo();");
		method.addBodyLine(" bo.setId(record.getId());");
		method.addBodyLine(" bos.add(bo);");
		method.addBodyLine(" }");
		method.addBodyLine("return bos;");

		method.addBodyLine(" } catch (ServiceException e) {");
		method.addBodyLine("logger.error(\"service Exception: \", e);");
		method.addBodyLine("return null;");
		method.addBodyLine(" }");
		return method;
	}

	/**
	 * 批量修改方法
	 * 
	 */
	protected Method batchModifyExample(IntrospectedTable introspectedTable,
			String tableName) {
		Method method = new Method();
		method.setName("updateByBatch");
		method.setReturnType(FullyQualifiedJavaType
				.getBooleanPrimitiveInstance());
		// method.setReturnRemark("返回baseResp对象");
		method.setReturnRemark("返回True Or  Flase");

		Parameter parameter = new Parameter(new FullyQualifiedJavaType(
				"List<Long>"), "ids");
		parameter.setRemark("主键列表");
		method.addParameter(parameter);

		parameter = new Parameter(pojoType, "po");
		parameter.setRemark("业务对象");
		method.addParameter(parameter);

		method.setVisibility(JavaVisibility.PUBLIC);
		StringBuilder sb = new StringBuilder();

		method.addBodyLine("try {");
		sb.append("int result=this.");
		sb.append(getDaoShort());
		sb.append("updateByBatch(");
		sb.append("ids,po");
		sb.append(");");
		method.addBodyLine(sb.toString());

		method.addBodyLine("if(result==1){");
		method.addBodyLine("return true;");
		method.addBodyLine("}");

		method.addBodyLine(" } catch (ServiceException e) {");
		method.addBodyLine("  logger.warn(\"service Exception: \", e);");

		method.addBodyLine(" }");
		method.addBodyLine("return false;");

		return method;
	}

	/**
	 * 批量删除
	 * 
	 */
	protected Method batchDeleteByExample(IntrospectedTable introspectedTable,
			String tableName) {
		Method method = new Method();
		// method.setName("batchDeleteBy" + tableName);
		method.setName("deleteByBatch");
		method.setReturnType(FullyQualifiedJavaType
				.getBooleanPrimitiveInstance());
		// method.setReturnRemark("返回baseResp对象");
		method.setReturnRemark("返回True Or  Flase");
		Parameter parameter = new Parameter(new FullyQualifiedJavaType(
				"List<Long>"), "ids");
		parameter.setRemark("主键列表");
		method.addParameter(parameter);
		method.setVisibility(JavaVisibility.PUBLIC);
		StringBuilder sb = new StringBuilder();

		method.addBodyLine("try {");

		sb.append("int result=this.");
		sb.append(getDaoShort());
		if (introspectedTable.hasBLOBColumns()) {
			sb.append("deleteByBatch");
		} else {
			sb.append("deleteByBatch");
		}
		sb.append("(");
		sb.append("ids");
		sb.append(");");
		method.addBodyLine(sb.toString());

		method.addBodyLine("if(result==1){");
		method.addBodyLine("return true;");
		method.addBodyLine("}");

		method.addBodyLine(" } catch (ServiceException e) {");
		method.addBodyLine("  logger.warn(\"service Exception: \", e);");

		method.addBodyLine(" }");
		method.addBodyLine("return false;");

		return method;
	}

	/**
	 * 添加方法
	 * 
	 */
	protected Method getOtherInsertBaseResp(String methodName,
			IntrospectedTable introspectedTable, String tableName) {
		Method method = new Method();
		method.setName(methodName);
		method.setReturnType(FullyQualifiedJavaType.getInteger());
		// method.setReturnRemark("返回baseResp对象");
		method.setReturnRemark("返回结束");
		Parameter parameter = new Parameter(pojoType, "po");
		parameter.setRemark("业务对象");
		method.addParameter(parameter);
		method.setVisibility(JavaVisibility.PUBLIC);

		// method.addBodyLine(" debug(\"" + method.getName() + "\", po);");
		// method.addBodyLine("BaseResp resp=new BaseResp();");
		// method.addBodyLine("resp.setRetCode(BaseResp.RC_OK);");
		// method.addBodyLine("resp.setRetMsg(\"请求成功\");");
		// method.addBodyLine("resp.setSuccess(true);");
		method.addBodyLine("try {");
		method.addBodyLine(" po.setId(IdUtils.id());");
		method.addBodyLine(" Date now = new Date();");
		method.addBodyLine(" po.setCreateTime(now);");
		// method.addBodyLine(" BeanUtils.copyProperties(bo, record);");
		StringBuilder sb = new StringBuilder();
		sb.append("int result=this.");
		sb.append(getDaoShort());
		sb.append(methodName);
		sb.append("(");
		sb.append("po");
		sb.append(");");
		method.addBodyLine(sb.toString());

		method.addBodyLine("return result;");

		method.addBodyLine(" } catch (ServiceException e) {");
		method.addBodyLine("  logger.warn(\"service Exception: \", e);");

		method.addBodyLine(" }");
		method.addBodyLine("return 0;");

		return method;
	}

	/**
	 * 添加方法
	 * 
	 */
	protected Method getOtherBaseResp(String methodName, String interfaceName,
			IntrospectedTable introspectedTable, String tableName, int type) {
		Method method = new Method();
		method.setName(methodName);
		method.setReturnType(FullyQualifiedJavaType.getInteger());
		method.setReturnRemark("返回结果");
		String params = addParams(introspectedTable, method, type);
		method.setVisibility(JavaVisibility.PUBLIC);

		// method.addBodyLine("BaseResp resp=new BaseResp();");
		// method.addBodyLine("resp.setRetCode(BaseResp.RC_OK);");
		// method.addBodyLine("resp.setRetMsg(\"请求成功\");");
		// method.addBodyLine("resp.setSuccess(true);");
		StringBuilder sb = new StringBuilder();
		method.addBodyLine("try {");

		sb.append("int result=this.");
		sb.append(getDaoShort());
		if (introspectedTable.hasBLOBColumns()
				&& (!"updateByPrimaryKeySelective".equals(interfaceName)
						&& !"deleteByPrimaryKey".equals(interfaceName)
						&& !"deleteByExample".equals(interfaceName) && !"updateByExampleSelective"
							.equals(interfaceName))) {
			sb.append(interfaceName + "WithoutBLOBs");
		} else {
			sb.append(interfaceName);
		}
		sb.append("(");
		sb.append(params);
		sb.append(");");
		method.addBodyLine(sb.toString());
		method.addBodyLine("return result;");
		method.addBodyLine("} catch (ServiceException e) {");
		method.addBodyLine("logger.warn(\"service Exception: \", e);");
		method.addBodyLine(" }");
		method.addBodyLine("return 0;");

		return method;
	}

	/**
	 * 添加方法
	 * 
	 */
	protected Method getOtherInteger(String methodName,
			IntrospectedTable introspectedTable, String tableName, int type) {
		Method method = new Method();
		method.setName(methodName);
		// method.setReturnRemark("返回baseResp对象");
		method.setReturnRemark("返回结束");
		String params = addParams(introspectedTable, method, type);
		method.setVisibility(JavaVisibility.PUBLIC);

		StringBuilder sb = new StringBuilder();
		sb.append("return this.");
		sb.append(getDaoShort());
		if (introspectedTable.hasBLOBColumns()
				&& (!"updateByPrimaryKeySelective".equals(methodName)
						&& !"deleteByPrimaryKey".equals(methodName)
						&& !"deleteByExample".equals(methodName) && !"updateByExampleSelective"
							.equals(methodName))) {
			sb.append(methodName + "WithoutBLOBs");
		} else {
			sb.append(methodName);
		}
		sb.append("(");
		sb.append(params);
		sb.append(");");
		method.addBodyLine(sb.toString());

		return method;
	}

	/**
	 * 添加参数
	 * 
	 * @param introspectedTable
	 * @param method
	 * @param type
	 *            type的意义 pojo 1 key 2 example 3 pojo+example 4
	 * @return
	 */
	protected String addParams(IntrospectedTable introspectedTable,
			Method method, int type1) {
		Parameter parameter = null;
		switch (type1) {
		case 1:
			parameter = new Parameter(pojoType, "po");
			parameter.setRemark("业务对象");
			method.addParameter(parameter);
			// method.addBodyLine(" debug(\"" + method.getName() + "\", po);");
			return "po";
		case 2:
			if (introspectedTable.getRules().generatePrimaryKeyClass()) {
				FullyQualifiedJavaType type = new FullyQualifiedJavaType(
						introspectedTable.getPrimaryKeyType());
				method.addParameter(new Parameter(type, "key"));
			} else {
				for (IntrospectedColumn introspectedColumn : introspectedTable
						.getPrimaryKeyColumns()) {
					FullyQualifiedJavaType type = introspectedColumn
							.getFullyQualifiedJavaType();
					parameter = new Parameter(type,
							introspectedColumn.getJavaProperty());
					parameter.setRemark("主键ID");
					method.addParameter(parameter);
				}
			}
			StringBuffer sb = new StringBuffer();
			for (IntrospectedColumn introspectedColumn : introspectedTable
					.getPrimaryKeyColumns()) {
				sb.append(introspectedColumn.getJavaProperty());
				sb.append(",");
			}
			if (sb.length() > 1) {
				sb.setLength(sb.length() - 1);
			}
			return sb.toString();
		case 3:
			method.addParameter(new Parameter(pojoCriteriaType, "criteria"));
			return "criteria";
		case 4:
			String tableName = introspectedTable.getFullyQualifiedTable()
					.toString();
			if (tableName != null && tableName.length() > 0) {
				tableName = tableName.replaceFirst(tableName.substring(0, 1),
						tableName.substring(0, 1).toUpperCase());
			} else {
				System.out
						.println("**********************表名为空**********************");
			}
			method.addParameter(0, new Parameter(pojoType, "record"));
			method.addParameter(1, new Parameter(pojoCriteriaType, "criteria"));
			if (method.getName().equals("updateBy" + tableName + "Selective")
					|| method.getName().equals("updateBy" + tableName)) {
				return "record, criteria.getCondition()";
			}
			return "record, criteria";
		case 5:
			parameter = new Parameter(qoType, "qo");
			parameter.setRemark("条件查询对象");
			method.addParameter(parameter);
			// method.addBodyLine(" debug(\"" + method.getName() + "\", qo);");
			return "qo";
		case 6:
			parameter = new Parameter(pojoType, "po");
			parameter.setRemark("业务对象");
			method.addParameter(0, parameter);
			parameter = new Parameter(qoType, "qo");
			parameter.setRemark("条件查询对象");
			method.addParameter(1, parameter);
			// method.addBodyLine(" debug(\"" + method.getName() + "\", bo);");
			return "bo, qo";
		default:
			break;
		}
		return null;
	}

	/**
	 * 添加注释
	 * 
	 * @param field
	 * @param comment
	 */
	protected void addComment(JavaElement field, String comment) {
		StringBuilder sb = new StringBuilder();
		field.addJavaDocLine("/**");
		sb.append(" * ");
		comment = comment.replaceAll(OutputUtilities.lineSeparator, "<br>"
				+ OutputUtilities.lineSeparator + "\t * ");
		sb.append(comment);
		field.addJavaDocLine(sb.toString());
		field.addJavaDocLine(" */");
	}

	/**
	 * 添加字段
	 * 
	 * @param topLevelClass
	 */
	protected void addField(TopLevelClass topLevelClass) {
		// 添加 success
		Field field = new Field();
		field.setName("success"); // 设置变量名
		field.setType(FullyQualifiedJavaType.getBooleanPrimitiveInstance()); // 类型
		field.setVisibility(JavaVisibility.PRIVATE);
		addComment(field, "执行结果");
		topLevelClass.addField(field);
		// 设置结果
		field = new Field();
		field.setName("message"); // 设置变量名
		field.setType(FullyQualifiedJavaType.getStringInstance()); // 类型
		field.setVisibility(JavaVisibility.PRIVATE);
		addComment(field, "消息结果");
		topLevelClass.addField(field);
	}

	/**
	 * 添加方法
	 * 
	 * @param topLevelClass
	 */
	protected void addMethod(TopLevelClass topLevelClass) {
		Method method = new Method();
		method.setVisibility(JavaVisibility.PUBLIC);
		method.setName("setSuccess");
		method.addParameter(new Parameter(FullyQualifiedJavaType
				.getBooleanPrimitiveInstance(), "success"));
		method.addBodyLine("this.success = success;");
		topLevelClass.addMethod(method);

		method = new Method();
		method.setVisibility(JavaVisibility.PUBLIC);
		method.setReturnType(FullyQualifiedJavaType
				.getBooleanPrimitiveInstance());
		method.setName("isSuccess");
		method.addBodyLine("return success;");
		topLevelClass.addMethod(method);

		method = new Method();
		method.setVisibility(JavaVisibility.PUBLIC);
		method.setName("setMessage");
		method.addParameter(new Parameter(FullyQualifiedJavaType
				.getStringInstance(), "message"));
		method.addBodyLine("this.message = message;");
		topLevelClass.addMethod(method);

		method = new Method();
		method.setVisibility(JavaVisibility.PUBLIC);
		method.setReturnType(FullyQualifiedJavaType.getStringInstance());
		method.setName("getMessage");
		method.addBodyLine("return message;");
		topLevelClass.addMethod(method);
	}

	/**
	 * 添加方法
	 * 
	 * @param topLevelClass
	 * @param tableName
	 *            表名
	 */
	protected void addMethod(TopLevelClass topLevelClass, String tableName) {
		Method method2 = new Method();
		for (int i = 0; i < methods.size(); i++) {
			Method method = new Method();
			method2 = methods.get(i);
			method = method2;
			method.removeAllBodyLines();
			method.removeAnnotation();
			StringBuilder sb = new StringBuilder();
			sb.append("return this.");
			sb.append(getDaoShort());
			sb.append(method.getName());
			sb.append("(");
			List<Parameter> list = method.getParameters();
			for (int j = 0; j < list.size(); j++) {
				sb.append(list.get(j).getName());
				sb.append(",");
			}
			sb.setLength(sb.length() - 1);
			sb.append(");");
			method.addBodyLine(sb.toString());
			topLevelClass.addMethod(method);
		}
		methods.clear();
	}

	/**
	 * BaseUsers to baseUsers
	 * 
	 * @param tableName
	 * @return
	 */
	protected String toLowerCase(String tableName) {
		StringBuilder sb = new StringBuilder(tableName);
		sb.setCharAt(0, Character.toLowerCase(sb.charAt(0)));
		return sb.toString();
	}

	/**
	 * BaseUsers to baseUsers
	 * 
	 * @param tableName
	 * @return
	 */
	protected String toUpperCase(String tableName) {
		StringBuilder sb = new StringBuilder(tableName);
		sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
		return sb.toString();
	}

	/**
	 * 导入需要的类
	 */
	private void addImport(Interface interfaces, TopLevelClass topLevelClass) {
		interfaces.addImportedType(pojoType);
		interfaces.addImportedType(pageBoundsType);
		interfaces.addImportedType(listType);
		topLevelClass.addImportedType(daoType);
		topLevelClass.addImportedType(interfaceType);
		topLevelClass.addImportedType(pojoType);
		topLevelClass.addImportedType(pageBoundsType);
		topLevelClass.addImportedType(qoType);
		topLevelClass.addImportedType(boType);
		topLevelClass.addImportedType(orderType);
		topLevelClass.addImportedType(serviceExceptionType);
		topLevelClass.addImportedType(listType);
		topLevelClass.addImportedType(slf4jLogger);
		// topLevelClass.addImportedType(serializable);
		topLevelClass.addImportedType(slf4jLoggerFactory);
		topLevelClass.addImportedType(pageList);
		topLevelClass.addImportedType(arrayList);
		topLevelClass.addImportedType(dateType);
		topLevelClass.addImportedType(idHelper);
		if (enableAnnotation) {
			topLevelClass.addImportedType(service);
			topLevelClass.addImportedType(autowired);
			topLevelClass.addImportedType(transactional);
		}
	}

	/**
	 * 导入logger
	 */
	private void addLogger(TopLevelClass topLevelClass) {
		Field field = new Field();
		field.setFinal(true);
		field.setInitializationString("LoggerFactory.getLogger("
				+ topLevelClass.getType().getShortName() + ".class)"); // 设置值
		field.setName("logger"); // 设置变量名
		field.setStatic(true);
		field.setType(new FullyQualifiedJavaType("Logger")); // 类型
		field.setVisibility(JavaVisibility.PRIVATE);
		topLevelClass.addField(field);
	}

	private String getDaoShort() {
		return toLowerCase(daoType.getShortName()) + ".";
	}

	public boolean clientInsertMethodGenerated(Method method,
			Interface interfaze, IntrospectedTable introspectedTable) {
		returnType = method.getReturnType();
		return true;
	}

	public void addMethodComment(Method method, String comments) {

		StringBuilder sb = new StringBuilder();
		String remark = comments;
		if (remark != null && remark.length() != 0) {
			method.addJavaDocLine("/**"); //$NON-NLS-1$
			sb.append(" * "); //$NON-NLS-1$
			remark = remark.replaceAll(OutputUtilities.lineSeparator, "<br>"
					+ OutputUtilities.lineSeparator + "\t * ");
			sb.append(remark);
			method.addJavaDocLine(sb.toString());
			method.addJavaDocLine(" *"); //$NON-NLS-1$ @param

			List<Parameter> parameters = method.getParameters();
			for (Parameter parameter : parameters) {// 判断是否有带代码
				sb = new StringBuilder();
				sb.append(" * ");
				sb.append("@param ");
				sb.append(parameter.getName() + " ");
				if (parameter.getRemark() != null) {
					sb.append(parameter.getRemark());
				}
				method.addJavaDocLine(sb.toString());
			}
			if (method.getReturnType() != null) {// 判断是否有返回值
				sb = new StringBuilder();
				sb.append(" * @return ");
				if (method.getReturnRemark() != null) {
					sb.append(method.getReturnRemark());
				}
				method.addJavaDocLine(sb.toString());
			}
			if (method.getExceptions() != null
					&& method.getExceptions().size() > 0) {// 判断是否抛出异常
				List<FullyQualifiedJavaType> types = method.getExceptions();
				for (FullyQualifiedJavaType type : types) {
					method.addJavaDocLine(" * @throws " + type.getShortName());
				}
			}
			method.addJavaDocLine(" */"); //$NON-NLS-1$
		}
	}

	public void addMethodAnnotation(Method method) {
		method.addAnnotation("@Transactional()");
	}

	@Override
	public List<GeneratedJavaScriptFile> contextGenerateAdditionalJavaScriptFiles() {
		// TODO Auto-generated method stub
		List<GeneratedJavaScriptFile> files = new ArrayList<GeneratedJavaScriptFile>(
				1);
		return files;
	}

	@Override
	public List<GeneratedJavaScriptFile> contextGenerateAdditionalJavaScriptFiles(
			IntrospectedTable introspectedTable) {
		List<GeneratedJavaScriptFile> files = new ArrayList<GeneratedJavaScriptFile>(
				1);
		return files;
	}

	/**
	 * 添加文件注释
	 * 
	 * @param compilationUnit
	 */
	public void addJavaFileComment(CompilationUnit compilationUnit) {
		List<String> comments = compilationUnit.getFileCommentLines();
		String title = "";
		String description = "";
		if (comments != null && comments.size() == 1) {
			title = comments.get(0);
		} else if (comments != null && comments.size() == 2) {
			title = comments.get(0);
			description = comments.get(1);
		}
		compilationUnit.clearFileCommentLine();
		compilationUnit.addFileCommentLine("/**");
		compilationUnit.addFileCommentLine(" * Title:" + title + "<br>");
		compilationUnit.addFileCommentLine(" * Description:" + description
				+ "<br>");
		compilationUnit
				.addFileCommentLine(" * ");
		compilationUnit.addFileCommentLine(" * @Create:"
				+ DateUtils.format(new Date(), "yyyy-MM-dd") + "<br>");
		compilationUnit.addFileCommentLine(" * @author:super_dev_001<br>");
		compilationUnit.addFileCommentLine(" * @version: Object v1.0.0<br>");
		compilationUnit.addFileCommentLine(" * <br>");
		compilationUnit.addFileCommentLine(" * 修改历史:<br>");
		compilationUnit.addFileCommentLine(" * 修改人		修改日期		修改描述<br>");
		compilationUnit
				.addFileCommentLine(" * -----------------------------------<br>");
		compilationUnit.addFileCommentLine(" * <br>");
		compilationUnit.addFileCommentLine(" * <br>");
		compilationUnit.addFileCommentLine(" */");
		// add no file level comments by default
		return;
	}
}
